package _03_myStringBuffer;

public final class MyStringBuffer implements java.io.Serializable {

    // 字符数组，私有成员变量
    private char[] value;
    // 串长度
    private int n;

    // 构造容量为capacity的空串
    public MyStringBuffer(int capacity) {
        this.value = new char[capacity];
        this.n = 0;
    }

    // 以默认容量构造空串
    public MyStringBuffer() {
        this(16);
    }

    // 以字符串常量构造串
    public MyStringBuffer(String s) {
        this(s.length() + 16);
        this.n = s.length();
        for (int i = 0; i < this.n; i++) {
            this.value[i] = s.charAt(i);
        }
    }

    // 返回字符串长度
    public int length() {
        return this.n;
    }

    // 返回字符数组容量
    public int capacity() {
        return this.value.length;
    }

    // 返回字符串描述
    public synchronized String toString() {
        return new String(this.value, 0, this.n);
    }

    // 返回第i个字符
    public synchronized char charAt(int i) {
        if (i >= 0 && i < this.n) {
            return this.value[i];
        }
        throw new StringIndexOutOfBoundsException(i);
    }

    // 设置第i个字符
    public void setCharAt(int i, char ch) {
        if (i >= 0 && i < this.n) {
            this.value[i] = ch;
        } else {
            throw new StringIndexOutOfBoundsException(i);
        }
    }

    // 在第i个字符处插入s串
    public synchronized MyStringBuffer insert(int i, String s) {
        if (i < 0) {
            i = 0;
        }
        if (i >= this.n) {
            i = this.n;
        }
        if (this.n == 0 && i == 0 || this.n > 0 && i >= 0 && i <= this.n) {
            if (s == null) {
                s = "";
            }
            char[] temp = this.value;
            if (this.value.length < this.n + s.length()) {
                this.value = new char[(this.value.length + s.length()) * 2];
                for (int j = 0; j < i; j++) {
                    this.value[j] = temp[j];
                }
            }
            for (int j = this.n - 1; j >= i; j--) {
                this.value[j + s.length()] = temp[j];
            }
            for (int j = 0; j < s.length(); j++) {
                this.value[i + j] = s.charAt(j);
            }
            this.n += s.length();
            return this;
        } else {
            throw new StringIndexOutOfBoundsException("i = "+i);
        }
    }
    
    // 在i处插入变量值转换成的串
    public synchronized MyStringBuffer insert(int i, boolean b) {
        return insert(i, b ? "true" : "false");
    }
    
    // 添加s串
    public synchronized MyStringBuffer append(String s) {
        return insert(this.n, s);
    }

    // 删除从begin到end-1的子串
    public synchronized MyStringBuffer delete(int begin, int end) {
        if (begin < 0) {
            begin = 0;
        }
        if (end > this.n) {
            end = this.n;
        }
        if (begin >= 0 && begin < this.n && end > 0 && end >= begin && end <= this.n) {
            for (int i = 0; i < this.n - end; i++) {
                this.value[i + begin] = this.value[i + end];
            }
            this.n -= end - begin;
            return this;
        } else {
            throw new StringIndexOutOfBoundsException("begin="+begin+"，end="+end+"，end-begin="+(end-begin));
        }
    }
    
    // 反转
    public MyStringBuffer reverse() {
        /*
        // 你这样反转引用的同时引用也在改变，你temp只是引用value而不是深拷贝value，浅拷贝value改变，temp也会跟着变
        char[] temp = this.value;
        for (int i = 0; i < this.n; i++) {
            this.value[i] = temp[this.n - i - 1];
            System.out.println(temp[this.n - i - 1]);
        }
        */
        // 需反转位置元素交换
        for (int i = 0; i < this.n/2; i++) {
            char temp = this.value[i];
            this.value[i] = this.value[this.n - i - 1];
            this.value[this.n - i - 1] = temp;
        }
        
        return this;
    }
    
 // Brute-Force字符串匹配算法
    public int BFIndexOf(String pattern, int begin) {
        int m = pattern.length();
        int n = this.length();
        if (begin < 0) {
            begin = 0;
        }
        if (n == 0 || n < m || m > n - begin) {
            return -1;
        }
        int i = begin;
        int j = 0;
        while (i < this.length() && j < pattern.length()) {
            if (this.charAt(i) == pattern.charAt(j)) {
                i++;
                j++;
            } else {
                i = i - j + 1;
                j = 0;
                if (m > n - i) {
                    break;
                }
            }
        }
        return j == pattern.length() ? i-j : -1;
    }
    
    
    // 将首个与pattern匹配的子串替换为s
    public MyStringBuffer replaceFirst(String pattern, String s) {
        int i = this.BFIndexOf(pattern, 0);
        if (i != -1) {
            this.delete(i, i + pattern.length());
            this.insert(i, s);
        }
        return this;
    }
    
    // 将所有与pattern匹配的子串替换为s
    public MyStringBuffer replaceAll(String pattern, String s) {
        int i = this.BFIndexOf(pattern, 0);
        while (i != -1) {
            this.delete(i, i + pattern.length());
            this.insert(i, s);
            i = this.BFIndexOf(pattern, i+s.length());
        }
        return this;
    }
    
    // 删除target串中所有与pattern匹配的子串，返回删除后的target串
    public MyStringBuffer removeAll(String pattern) {
        int next = this.BFIndexOf(pattern, 0);
        int empty = next;
        while (next != -1) {
            int move = next + pattern.length();
            next = this.BFIndexOf(pattern, move);
            while (next > 0 && move < next || next == -1 && move < this.n) {
                this.setCharAt(empty++, this.charAt(move++));
            }
        }
        if (empty != -1) {
            this.n = empty;
        }
        return this;
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyStringBuffer msb = new MyStringBuffer("abc123");
        System.out.println("测试toString方法：");
        System.out.println(msb.toString());
        System.out.println("测试insert方法：");
        System.out.println(msb.insert(0, "I").toString());
        System.out.println(msb.insert(6, "I").toString());
        System.out.println(msb.insert(3, false));
        System.out.println("测试append方法：");
        System.out.println(msb.append("def"));
        System.out.println("测试delete方法：");
        System.out.println(msb.delete(3, 8));
        System.out.println("测试reverse方法：");
        System.out.println(msb.reverse());
        System.out.println("测试replaceFirst(String, String)方法：");
        System.out.println(msb.replaceFirst("I", "aaa"));
        System.out.println("测试replaceAll(String, String)方法：");
        System.out.println(msb.replaceAll("a", "(@_@)"));
        System.out.println("测试removeAll(String)方法：");
        System.out.println(msb.removeAll("@"));
        
    }

}
